﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using MiniFox.Configurations;
using MiniFox.Web.Configurations;
using MiniFox.Web.Configurations.CrossDomain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace MiniFox.Web.Middlewares
{
    /// <summary>
    /// 
    /// </summary>
    public class CrossDomainMiddleware : MiddlewareBase
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        protected override void BeforeInvoke(MiddlewareContext context)
        {
            HttpContext httpContext = context.CurrentHttpContext;
            HttpRequest request = httpContext.Request;
            HttpResponse response = httpContext.Response;
            if (!string.Equals(request.Method, CrossDomainParamsKey.HTTP_METHOD_OPTIONS, StringComparison.OrdinalIgnoreCase))
            {
                return;
            }
            var configuration = ConfigurationFactory.GetConfig<WebConfiguration>();
            var crossDomainConfig = configuration.CrossDomain;
            if (crossDomainConfig == null)
                return;

            string origin = request.Headers["Origin"].ToString();
            if (string.IsNullOrEmpty(origin))
            {
                return;
            }


            if (crossDomainConfig.Origins.Contains(origin))
                response.Headers.Append(CrossDomainParamsKey.ACCESS_CONTROL_ALLOW_ORIGIN, origin);

            if (crossDomainConfig.Credentials)
                response.Headers.Append(CrossDomainParamsKey.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");

            if (crossDomainConfig.Headers != null && crossDomainConfig.Headers.Length > 0)
                response.Headers.Append(CrossDomainParamsKey.ACCESS_CONTROL_ALLOW_HEADERS, crossDomainConfig.Headers);
            if (crossDomainConfig.Methods != null && crossDomainConfig.Methods.Length > 0)
                response.Headers.Append(CrossDomainParamsKey.ACCESS_CONTROL_ALLOW_METHODS, crossDomainConfig.Methods);
            if (crossDomainConfig.MaxAge > 0)
                response.Headers.Append(CrossDomainParamsKey.ACCESS_CONTROL_MAX_AGE, crossDomainConfig.MaxAge.ToString());

            switch (request.Method.ToUpper())
            {
                case WebRequestMethods.Http.Get:
                case WebRequestMethods.Http.Post:
                case WebRequestMethods.Http.Head:
                    if (crossDomainConfig.ExposeHeaders != null && crossDomainConfig.ExposeHeaders.Length > 0)
                        response.Headers.Append(CrossDomainParamsKey.ACCESS_CONTROL_EXPOSE_HEADERS, crossDomainConfig.ExposeHeaders);
                    break;
                default:
                    break;
            }
            context.Cancel = true;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        protected override void AfterInvoke(MiddlewareContext context)
        {
            HttpContext httpContext = context.CurrentHttpContext;
            HttpRequest request = httpContext.Request;
            //HttpResponse response = httpContext.Response; 
            if (!string.Equals(request.Method, CrossDomainParamsKey.HTTP_METHOD_OPTIONS, StringComparison.OrdinalIgnoreCase))
            {
                return;
            }
            //await response.CompleteAsync();
        }
    }
}
